package cn.fcq.ymcc.service.impl;

import cn.fcq.ymcc.constants.CommonConstants;
import cn.fcq.ymcc.constants.SmsCodeConstants;
import cn.fcq.ymcc.constants.YmccError;
import cn.fcq.ymcc.domain.MessageSms;
import cn.fcq.ymcc.dto.RedisRegisterDto;
import cn.fcq.ymcc.exception.GlobalException;
import cn.fcq.ymcc.service.IMessageSmsService;
import cn.fcq.ymcc.service.IVerifyCodeService;
import cn.fcq.ymcc.util.AssertUtil;
import cn.fcq.ymcc.util.StrUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private IMessageSmsService messageSmsService;

    @Autowired
    private SmsCodeConstants smsCodeConstants;
    /**
     * 一：校验
     *  1.空校验
     *  2.格式校验
     * 二：验证码
     *  1.校验手机号是否发送过验证码
     *  2.从redis拿到了
     *    2.1 没有过重发时间，使劲骂
     *    2.2 过了重发时间，使用还未过期的码儿
     *  3.拿不到
     * 3.1.生成验证码
     * 3.2.存储验证码
     * 3.3.发送验证码短信
     * 3.4.存储发送信息到数据库
     * @param mobile
     */
    @Override
    public void smsCode(String mobile) {
         //* 一：校验
         //*  1.空校验
        AssertUtil.isNotEmpty(mobile,YmccError.COMMON_PHONE_NO_EMPTY.getMessage());
        AssertUtil.isPhone(mobile,YmccError.COMMON_PHONE_ILLEGAL.getMessage());
        /*if (StringUtils.isEmpty(mobile)){
            throw new GlobalException(YmccError.COMMON_PHONE_NO_EMPTY.getMessage(),
                    YmccError.COMMON_PHONE_NO_EMPTY.getCode());
        }*/
         //*  2.格式校验
         //* 二：验证码
        String key=String.format(CommonConstants.REGISTER_PHONE_PRIFIX,mobile);
        Date nowDate = new Date();
         //*  1.校验手机号是否发送过验证码
        Object o = redisTemplate.opsForValue().get(key);
        String code=null;
        if (o !=null){
            //*  2.从redis拿到了
            RedisRegisterDto registerDto=(RedisRegisterDto) o;
            if (nowDate.getTime()-registerDto.getTime()/1000<smsCodeConstants.getInterval()) {
                //*    2.1 没有过重发时间
                throw new GlobalException(YmccError.COMMON_SERIOUS.getMessage(),
                        YmccError.COMMON_SERIOUS.getCode());
            }
            //2.2 过了重发时间，使用还未过期的码儿
            code = registerDto.getCode();

        }else {
            //*  3.拿不到
            //* 3.1.生成验证码
            code= StrUtils.getComplexRandomString(smsCodeConstants.getSize());
        }
         //* 3.2.存储验证码
        RedisRegisterDto redisRegisterDto = new RedisRegisterDto(code, nowDate.getTime());
        redisTemplate.opsForValue().set(key,redisRegisterDto,smsCodeConstants.getTimeout(), TimeUnit.SECONDS);
        //* 3.3.发送验证码短信
        String message = String.format(smsCodeConstants.getSmsmessage(), code);
        log.info(message);
         //* 3.4.存储发送信息到数据库
        saveMessageSms(nowDate,code,message);


    }

    private void saveMessageSms(Date nowDate, String code,String message) {
        MessageSms messageSms = new MessageSms();
        messageSms.setContent(message);
        messageSms.setSendTime(nowDate);
        messageSms.setTitle(smsCodeConstants.getTitle());
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        messageSms.setIp(request.getRemoteAddr());
        messageSmsService.insert(messageSms);
    }
}
